package fr.imag.ufrima.ima.project.ui.tools;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;

import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import org.apache.log4j.Logger;

import fr.imag.ufrima.ima.project.core.Image;
import fr.imag.ufrima.ima.project.core.operations.Fusion;
import fr.imag.ufrima.ima.project.core.operations.NoOperation;
import fr.imag.ufrima.ima.project.core.operations.TypeFusion;
import fr.imag.ufrima.ima.project.ui.main.ImageProject;

public class FusionTool extends JPanel implements PropertyChangeListener {
	private Logger logger = Logger.getLogger(getClass().getName());
	
	private ImageProject imageProject;
	private File fusionFile;
	private boolean repeat;	
	private JComboBox cmbTypeFusion;
	private BufferedImage beforeFusionImage;
	
	private JButton btnApply;
	private JTextField txtFile;

	
	/**
	 * Create the panel.
	 */
	public FusionTool(ImageProject imageProject) {
		this.imageProject = imageProject;

		setLayout(new BorderLayout(0, 0));
		
		JPanel panel = new JPanel();		
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = new int[]{200};
		gbl_panel.rowHeights = new int[]{0};
		gbl_panel.columnWeights = new double[]{1.0};
		gbl_panel.rowWeights = new double[]{1.0};
		panel.setLayout(gbl_panel);

		add(panel, BorderLayout.NORTH);	
		
		JPanel panel_1 = new JPanel();
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.insets = new Insets(10, 10, 10, 10);
		gbc_panel_1.fill = GridBagConstraints.BOTH;
		gbc_panel_1.gridx = 0;
		gbc_panel_1.gridy = 0;
		panel.add(panel_1, gbc_panel_1);
		GridBagLayout gbl_panel_1 = new GridBagLayout();
		gbl_panel_1.columnWidths = new int[]{75, 75};
		gbl_panel_1.rowHeights = new int[]{0};
		gbl_panel_1.columnWeights = new double[]{0.5, 0.5};
		gbl_panel_1.rowWeights = new double[]{0.0};
		panel_1.setLayout(gbl_panel_1);
		
		JLabel lblImage = new JLabel("Image:");
		GridBagConstraints gbc_lblImage = new GridBagConstraints();
		gbc_lblImage.anchor = GridBagConstraints.WEST;
		gbc_lblImage.insets = new Insets(0, 0, 5, 5);
		gbc_lblImage.gridx = 0;
		gbc_lblImage.gridy = 0;
		panel_1.add(lblImage, gbc_lblImage);
		
		txtFile = new JTextField();
		txtFile.setEditable(false);
		GridBagConstraints gbc_txtFile = new GridBagConstraints();
		gbc_txtFile.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtFile.insets = new Insets(0, 0, 5, 5);
		gbc_txtFile.gridx = 0;
		gbc_txtFile.gridy = 1;
		panel_1.add(txtFile, gbc_txtFile);
		txtFile.setColumns(10);
		
		JButton btnBrowse = new JButton("Parcourir...");
		btnBrowse.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				FusionTool.this.selectFile();
			}
		});
		GridBagConstraints gbc_btnBrowse = new GridBagConstraints();
		gbc_btnBrowse.insets = new Insets(0, 0, 5, 0);
		gbc_btnBrowse.gridx = 1;
		gbc_btnBrowse.gridy = 1;
		panel_1.add(btnBrowse, gbc_btnBrowse);
		
		JLabel lblIntensit = new JLabel("Intensité:");
		GridBagConstraints gbc_lblIntensit = new GridBagConstraints();
		gbc_lblIntensit.anchor = GridBagConstraints.WEST;
		gbc_lblIntensit.insets = new Insets(0, 0, 5, 5);
		gbc_lblIntensit.gridx = 0;
		gbc_lblIntensit.gridy = 2;
		panel_1.add(lblIntensit, gbc_lblIntensit);
		
		cmbTypeFusion = new JComboBox();
		GridBagConstraints gbc_comboBox = new GridBagConstraints();
		gbc_comboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_comboBox.insets = new Insets(0, 0, 5, 0);
		gbc_comboBox.gridx = 1;
		gbc_comboBox.gridy = 2;
		panel_1.add(cmbTypeFusion, gbc_comboBox);
		cmbTypeFusion.setModel(new DefaultComboBoxModel(TypeFusion.values()));
		
		JLabel lblNewLabel = new JLabel("Strategie:");
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel.gridx = 0;
		gbc_lblNewLabel.gridy = 3;
		panel_1.add(lblNewLabel, gbc_lblNewLabel);
		
		JRadioButton rdbtnNoRepeat = new JRadioButton("No Repeat");
		rdbtnNoRepeat.setSelected(true);
		rdbtnNoRepeat.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				FusionTool.this.setRepeat(false);
			}
		});
		GridBagConstraints gbc_rdbtnNoRepeat = new GridBagConstraints();
		gbc_rdbtnNoRepeat.fill = GridBagConstraints.BOTH;
		gbc_rdbtnNoRepeat.insets = new Insets(0, 0, 5, 0);
		gbc_rdbtnNoRepeat.gridx = 1;
		gbc_rdbtnNoRepeat.gridy = 3;
		panel_1.add(rdbtnNoRepeat, gbc_rdbtnNoRepeat);
		
		JRadioButton rdbtnRepeat = new JRadioButton("Repeat");
		rdbtnRepeat.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				FusionTool.this.setRepeat(true);
			}
		});
		GridBagConstraints gbc_rdbtnRepeat = new GridBagConstraints();
		gbc_rdbtnRepeat.insets = new Insets(0, 0, 5, 0);
		gbc_rdbtnRepeat.fill = GridBagConstraints.BOTH;
		gbc_rdbtnRepeat.gridx = 1;
		gbc_rdbtnRepeat.gridy = 4;
		panel_1.add(rdbtnRepeat, gbc_rdbtnRepeat);				
		
		 //Group the radio buttons.
	    ButtonGroup group = new ButtonGroup();
	    group.add(rdbtnNoRepeat);
	    group.add(rdbtnRepeat);
	    
		btnApply = new JButton("Appliquer");
		btnApply.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				FusionTool.this.applyFusion();
			}
		});
		
		JButton btnCancel = new JButton("Annuler");
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				FusionTool.this.cancel();
			}
		});
		GridBagConstraints gbc_btnAnnuler = new GridBagConstraints();
		gbc_btnAnnuler.insets = new Insets(0, 0, 0, 5);
		gbc_btnAnnuler.gridx = 0;
		gbc_btnAnnuler.gridy = 5;
		panel_1.add(btnCancel, gbc_btnAnnuler);
		GridBagConstraints gbc_btnFusion31 = new GridBagConstraints();
		gbc_btnFusion31.gridx = 1;
		gbc_btnFusion31.gridy = 5;
		panel_1.add(btnApply, gbc_btnFusion31);

	}

	private void initTool() {
		beforeFusionImage = imageProject.getCurrentImageDocument().getImage().getBufferedImage();
		txtFile.setText("");
		btnApply.setEnabled(false);
	}
	
	private void selectFile() {
		fusionFile = imageProject.getFm().openFileDialog();
		
		if (fusionFile != null) {
			txtFile.setText(fusionFile.getAbsolutePath());
			btnApply.setEnabled(true);
		}
	}
	
	private void setRepeat(boolean repeatValue) {
		repeat = repeatValue;
	}
	
	private void applyFusion() {
		logger.info(String.format("Preparing to apply fusion..."));
		
		Image fusionImage = new Image(fusionFile.getAbsolutePath());
	
		Fusion fusion = new Fusion(imageProject.getCurrentImageDocument().getImage());
		fusion.setFusionImage(fusionImage);
		switch(cmbTypeFusion.getSelectedIndex()) {
		case 0: fusion.setTypeFusion(TypeFusion.LOW);
				break;
		case 1: fusion.setTypeFusion(TypeFusion.MEDIUM);
				break;
		case 2: fusion.setTypeFusion(TypeFusion.HIGH);
				break;
		}		
		fusion.setRepeat(this.repeat);
				
		imageProject.applyOperation(fusion);
				
		logger.info(String.format("Fusion ended."));
	}
	
	private void cancel() {
		logger.info(String.format("Preparing to revert fusion..."));
		
		NoOperation noOperation = new NoOperation(null);
		noOperation.setImage(beforeFusionImage);
		
		imageProject.applyOperation(noOperation);
		
		logger.info(String.format("Revertion ended."));
	}
	
	@Override
	public void propertyChange(PropertyChangeEvent e) {
		// TODO Auto-generated method stub
		String propertyName = e.getPropertyName();
		if ("visible".equals(propertyName)) {
			if ("true".equals(e.getNewValue().toString())) {
				logger.debug(String.format("FusionTool has become visible.", propertyName));
				initTool();
			}
		}
	}

	public PropertyChangeListener getPropertyChangeListener() {
		return this;
	}
}
